iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0
Software Development

開心撰寫 PHPUnit系列 第 18

Day 18. 重構程式碼 - 讓程式更容易擴充

  • 分享至 

  • xImage
  •  

在上篇我們提到希望最終的程式碼是呈現這樣

$crawler = new PttCrawler();
// 抓取所有看版及文章
$crawler->all();
// 抓取特定看版及看版文章
$crawler->get($boardName);

所以我們的第一步是可以把 PttCrawler 的所有程式移到到 Crawlers/Home.php 裡,在移動程式碼之前請先執行一次測試確保綠燈後再把程式碼調整為

<?php
// src/Crawlers/Home.php

namespace Recca0120\Ithome30\Crawlers;

use GuzzleHttp\Psr7\Request;
use Psr\Http\Client\ClientInterface;

class Home
{
    public function __construct(private ClientInterface $httpClient)
    {
    }

    public function all()
    {
        $request = new Request('GET', 'https://www.ptt.cc/bbs/hotboards.html');
        $response = $this->httpClient->sendRequest($request);
        $html = (string) $response->getBody();

        return array_map(
            fn (string $row) => $this->parseCols($row),
            $this->parseRows($html)
        );
    }

    private function parseCols($row)
    {
        preg_match('/href="(?<url>.+)"/', $row, $matched);
        preg_match_all('/"board-(?<name>\w+)">(?<value>.+?)<\/div>/', $row, $matches);
        $cols = ['url' => 'https://www.ptt.cc' . $matched['url']];
        foreach (array_keys($matches[0]) as $index) {
            $name = $matches['name'][$index];
            $value = $matches['value'][$index];
            $cols[$name] = str_replace('◎', '', strip_tags($value));
        }

        return $cols;
    }

    private function parseRows($html)
    {
        preg_match_all('/<a\sclass="board"[^>]*>.+?<\/a>/s', $html, $matches);

        return $matches[0];
    }
}
<?php
// src/PttCrawler.php

namespace Recca0120\Ithome30;

use Psr\Http\Client\ClientInterface;
use Recca0120\Ithome30\Crawlers\Home;

class PttCrawler
{
    public function __construct(private ClientInterface $httpClient)
    {
    }

    public function all()
    {
        $crawler = new Home($this->httpClient);

        return $crawler->all();
    }
}

調整完畢後再執行一次測試確保再次得到綠燈。

為什麼要做這一步的重構?

不進行重構,我們則會在 PttCrawler 這隻程式接著寫出文章列表的程式,如果今天的需求再增加了需要分析文章的回覆呢?是不是 PttCrawler 這隻程式就會越來越肥大了?而且職責就不單一了(負責分析看版、看版文章)!

這一步的重構是非常重要的,我們可以建立各個不同 class 來負責個各個不同的頁面,例如

  • Home.php -> 負責看版列表
  • Board.php -> 負責看版文章列表
  • Article.php -> 負責文章明細

這樣是不是明確多了?

測試的目地

寫測試最重要的是程式開發及重構,驗證只是程式開發及重構的一環,如果把驗證視為測試最重要的一件事,那對於開發人員來說,寫測試真的是浪費時間啊


上一篇
Day 17. code review 程式
下一篇
Day19. 擴充爬蟲測試 - 思考抓取列表方案
系列文
開心撰寫 PHPUnit30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言